/*
 * Copyright 2006-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package asphalt2.util
{
	import asphalt2.util.EventUtil;
	
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.ui.Keyboard;
	import flash.utils.Dictionary;
	
	import mx.controls.Button;
	import mx.core.Container;
	import mx.managers.ISystemManager;
	/**
	 * ボタン用ユーティリティ
	 * @author c9katayama
	 */
	[Mixin]
	public class ButtonUtils
	{
		private static var keyDownFlagPool:Dictionary = new Dictionary(true);
		
		private static var enterKeyDown:Boolean;
		
	    public static function init( sm:ISystemManager):void{
	    	//グローバルのキーボードイベントを取得して、実際にEnterキーが押されているかどうかを監視します。
	    	sm.addEventListener(KeyboardEvent.KEY_DOWN,function(e:KeyboardEvent):void{
	    		if(e.keyCode==Keyboard.ENTER){
	    			enterKeyDown = true;
	    		}
	    	},false);
	    	sm.addEventListener(KeyboardEvent.KEY_UP,function(e:KeyboardEvent):void{
	    		if(e.keyCode==Keyboard.ENTER){
	    			enterKeyDown = false;
	    		}
	    	},false);
	    }
		public static function isEnterKeydown():Boolean{
			return enterKeyDown;
		}
		/**
		 * enabledに連動してボタンモードが変わるハンドラーをセットします。
		 **/		
		public static function addButtonModeHandler(target:Button):void{
			target.buttonMode=target.enabled;
			target.addEventListener("enabledChanged",buttonEnabledChanegeHandler,false,0,true);
		}
		private static function buttonEnabledChanegeHandler(event:Event):void{
			var button:Button = Button(event.target); 
			button.buttonMode=button.enabled;	
		}
		
		/**
		 * Enterキー押下時にClickイベントを発生させるハンドラーをセットします。
		 **/
		public static function addEnterKeyClickHandler(target:Button):void{
			target.addEventListener(KeyboardEvent.KEY_UP,buttonKeyUpHandler,false,0,true);
			target.addEventListener(KeyboardEvent.KEY_DOWN,buttonKeyDownHandler,false,0,true);			
		}
		private static function buttonKeyDownHandler(event:KeyboardEvent):void{
	    	var button:Button = Button(event.target);
	    	var buttonKeydown:* = keyDownFlagPool[button];
	    	if(buttonKeydown == null){
	    		buttonKeydown = false;
	    	}
	    	if(ButtonUtils.isEnterKeydown()==false&&buttonKeydown==false){    		
		        if(event.keyCode == Keyboard.ENTER){
					Button(event.target).dispatchEvent(new MouseEvent(MouseEvent.CLICK));
				}
			}
			keyDownFlagPool[button] = true;
	    }
	    private static function buttonKeyUpHandler(event:KeyboardEvent):void{
			keyDownFlagPool[Button(event.target)] = false;			
		}
				
		/**
		 * 対象container中のコンポーネントをEnterしたときに押されるデフォルトボタンを設定します。
		 * FlexのdefaultButtonの場合、Enterを押しっぱなしにすると連続して呼び出されてしまうため、この実装はそれを抑制します。
		 **/
		public static function setDefaultButton(container:Container,defaultButton:Button):void{
			defaultButton.emphasized = true;
			container.addEventListener(KeyboardEvent.KEY_DOWN,createDefaultButtonHandler(defaultButton),false,0,true);
		}
		private static function createDefaultButtonHandler(defaultButton:Button):Function{
			return function(e:KeyboardEvent):void{
				if(e.keyCode==Keyboard.ENTER && e.target != defaultButton && ButtonUtils.isEnterKeydown()== false){
					defaultButton.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
				}
			}
		}
	}
}